package org.ikastola

import ikastola.Constants;

import org.springframework.dao.DataIntegrityViolationException
import org.springframework.transaction.annotation.Transactional;
import grails.plugins.springsecurity.Secured

@Secured(['ROLE_ADMIN'])
class FeeController {

    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

    def index() {
        redirect(action: "list", params: params)
    }

    def list(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        [feeInstanceList: Fee.findAllByDeleted(Constants.NOT_DELETED, params), feeInstanceTotal: Fee.countByDeleted(Constants.NOT_DELETED)]
    }

    def create() {
		session.feeDetails = []
        [feeInstance: new Fee(params)]
    }

	@Transactional
    def save() {
        
		def feeInstance = new Fee(params)
		
		Double totalValue = 0
		
		if (session.feeDetails) {
			for (f in session.feeDetails) {
				f.setDeleted(Constants.NOT_DELETED);
				f.setClassCreated(new Date())
				feeInstance.addToFeeDetails(f)
				totalValue = totalValue + f.getValue()
			}
			feeInstance.setValue(totalValue)
		}
		else {
			if (!params.adddetail) {
				feeInstance.setValue(new Double(params.value))
			} else  {
				flash.message = "Se ha seleccionado 'Contiene detalles'. No se han agregado detalles a la tarifa."
				redirect(action: "create")
				return
			}
		}
		
		feeInstance.setDeleted(Constants.NOT_DELETED)
		feeInstance.setClassCreated(new Date())
        if (!feeInstance.save(flush: true)) {
            render(view: "create", model: [feeInstance: feeInstance])
            return
        }

        flash.message = message(code: 'default.created.message', args: [message(code: 'fee.label', default: 'Fee'), feeInstance.id])
        redirect(action: "show", id: feeInstance.id)
    }

    def show(Long id) {
        def feeInstance = Fee.get(id)
        if (!feeInstance || Constants.DELETED.equals(feeInstance.getDeleted())) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'fee.label', default: 'Fee'), id])
            redirect(action: "list")
            return
        }

        [feeInstance: feeInstance]
    }

    def edit(Long id) {
        def feeInstance = Fee.get(id)
        if (!feeInstance || Constants.DELETED.equals(feeInstance.getDeleted())) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'fee.label', default: 'Fee'), id])
            redirect(action: "list")
            return
        }

        [feeInstance: feeInstance]
    }

	@Transactional
    def update(Long id, Long version) {
        def feeInstance = Fee.get(id)
        if (!feeInstance || Constants.DELETED.equals(feeInstance.getDeleted())) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'fee.label', default: 'Fee'), id])
            redirect(action: "list")
            return
        }

        if (version != null) {
            if (feeInstance.version > version) {
                feeInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
                          [message(code: 'fee.label', default: 'Fee')] as Object[],
                          "Another user has updated this Fee while you were editing")
                render(view: "edit", model: [feeInstance: feeInstance])
                return
            }
        }

        feeInstance.properties = params
		feeInstance.setValue(new Double(params.value))
		feeInstance.setClassUpdated(new Date())
        if (!feeInstance.save(flush: true)) {
            render(view: "edit", model: [feeInstance: feeInstance])
            return
        }

        flash.message = message(code: 'default.updated.message', args: [message(code: 'fee.label', default: 'Fee'), feeInstance.id])
        redirect(action: "show", id: feeInstance.id)
    }

	@Transactional
    def delete(Long id) {
        def feeInstance = Fee.get(id)
        if (!feeInstance || Constants.DELETED.equals(feeInstance.getDeleted())) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'fee.label', default: 'Fee'), id])
            redirect(action: "list")
            return
        }
		
		def dateDiscount = DateDiscount.findByFeeAndDeleted(feeInstance,Constants.NOT_DELETED)
		if (dateDiscount) {
			flash.message = "La Matricula/Cuota no puede ser eliminada dado que est&aacute; asignada a una Bonificaci&oacute;n."
			redirect(action: "list")
			return
		}
		
		def discount = Discount.findByFeeAndDeleted(feeInstance, Constants.NOT_DELETED)
		if (discount) {
			flash.message = "La Matricula/Cuota no puede ser eliminada dado que est&aacute; asignada a un Descuento."
			redirect(action: "list")
			return
		}
		
		def feeInter = FeeInter.findByFeeAndDeleted(feeInstance, Constants.NOT_DELETED)
		if (feeInter) {
			flash.message = "La Matricula/Cuota no puede ser eliminada dado que est&aacute; asignada a un Interes."
			redirect(action: "list")
			return
		}
		
		def services = Service.findAllByFees(feeInstance)
		if (services) {
			flash.message = "La Matricula/Cuota no puede ser eliminada dado que est&aacute; asignada a un Alumno."
			redirect(action: "list")
			return
		}
		
        try {
			feeInstance.setDeleted(Constants.DELETED)
			feeInstance.setClassUpdated(new Date())
			feeInstance.save(flush: true)
            flash.message = message(code: 'default.deleted.message', args: [message(code: 'fee.label', default: 'Fee'), id])
            redirect(action: "list")
        }
        catch (DataIntegrityViolationException e) {
            flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'fee.label', default: 'Fee'), id])
            redirect(action: "show", id: id)
        }
    }
	
	def addDetail() {
		def feeDetailInstance = new FeeDetail()
		feeDetailInstance.setDescription(params.ddesc)
		feeDetailInstance.setName(params.dname)
		feeDetailInstance.setValue(new Double(params.dvalue))
		def details = []
		Long i = 0
		if(!session.feeDetails) {
			session.feeDetails = details
		}
		details = session.feeDetails
		details.add(feeDetailInstance)
		session.feeDetails = details

		String names = ""
		for(FeeDetail f in details) {
			names = names + "<tr class='"+ ((i % 2) == 0 ? "even" : "odd") + "'><td>"+ f.getName() + "</td><td>" + f.getDescription() + "</td><td>" + String.valueOf(f.getValue()) + "</td><td>"  + remoteLink(update:'updateMe', action:'removeDetail',id: i) {"Eliminar"} + "</td></tr>"
			i++
		}
		
		String header = "<table><thead><tr><th>Nombre</th><th>Descripci&oacute;n</th><th>Monto</th><th>Acci&oacute;n</th></tr></thead><tbody>"
		String tail = "</tbody></table>"
		
		String html = header + names + tail

		render(text: html, contentType: "text/html", encoding: "UTF-8")
	}
	
	def removeDetail(Long id) {
		def details
		Long i = 0
		if(!session.feeDetails) {
			return
		}
		details = session.feeDetails
		def detail = details.getAt(id.toInteger())
		details = details.minus(detail)
		//System.out.println(checks)
		session.feeDetails = details
		String names = ""
		for(FeeDetail f in details) {
			names = names + "<tr class='"+ ((i % 2) == 0 ? 'even' : 'odd') + "'><td>"+ f.getName() + "</td><td>" + f.getDescription() + "</td><td>" + String.valueOf(f.getValue()) + "</td><td>" + remoteLink(update:'updateMe', action:'removeDetail',id: i) {"Eliminar"} + "</td></tr>"
			i++
		}
		
		String header = "<table><thead><tr><th>Nombre</th><th>Descripci&oacute;n</th><th>Monto</th><th>Acci&oacute;n</th></tr></thead><tbody>"
		String tail = "</tbody></table>"
		
		String html = names.equals("") ? names : header + names + tail
		
		render(text: html, contentType: "text/html", encoding: "UTF-8")
	}
}
